package com.tsd.system.entity;

import cn.hutool.json.JSONUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.fastjson.JSON;
import com.tsd.core.constants.Constants;
import com.tsd.core.datasource.DataSourceContextHolder;
import com.tsd.core.datasource.DataSourceProperties;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.JdbcUtil;
import io.swagger.annotations.ApiModel;

import java.io.Serializable;
import java.util.*;

/**
 * 系统账套扩展
 *
 * @author huawei
 * @date 2021/09/02 21:46:17
 */
@ApiModel(description = "系统账套扩展")
public class SysAccountSetExt extends SysAccountSet implements Serializable {
    /**
     * 归属人姓名
     */
    String owner_name;
    long execute_duration_sec;

    private boolean log = false;

    private List<String> sid_list;

    public String getOwner_name() {
        return owner_name;
    }

    public void setOwner_name(String owner_name) {
        this.owner_name = owner_name;
    }

    public boolean is_valid() {
        return getDr() != null && getDr() == 0
                && getState() == Constants.STATE_DB_CREATED;
    }

    public long getExecute_duration_sec() {
        long d = 0;
        if (getState() != null && getState() == Constants.STATE_DB_CREATING) {
            d = (System.currentTimeMillis() - (getCreate_begin() != null ? getCreate_begin().getTime() : System.currentTimeMillis())) / 1000;
        }
        return d;
    }

    public void setExecute_duration_sec(long execute_duration_sec) {
        this.execute_duration_sec = execute_duration_sec;
    }

    public boolean isLog() {
        return log;
    }

    public void setLog(boolean log) {
        this.log = log;
    }

    public List<String> getSid_list() {
        return sid_list;
    }

    public void setSid_list(List<String> sid_list) {
        this.sid_list = sid_list;
    }

    public boolean isMaster() {
        return DataSourceContextHolder.DEFAULT_ACCOUNT_SET_SID.equals(this.getSid());
    }

    public List<String> getModeList() {
        if (!HlpUtils.isEmpty(this.getMode()) && JSONUtil.isJsonArray(this.getMode())) {
            return JSON.parseArray(this.getMode(), String.class);
        }
        return null;
    }

    /**
     * 是否包含某个模块
     *
     * @param mod
     * @return
     */
    public boolean hasModule(String mod) {
        List<String> list = getModeList();
        if (list != null) {
            return list.contains(mod);
        }
        return false;
    }

    public SysAccountSetExt copy4Update(List<String> modeList) {
        SysAccountSetExt accountSetExt = new SysAccountSetExt();
        accountSetExt.setSid(this.getSid());
        accountSetExt.setCode(this.getCode());
        accountSetExt.setDb_host(this.getDb_host());
        accountSetExt.setDb_port(this.getDb_port());
        accountSetExt.setDb_name(this.getDb_name());
        accountSetExt.setDriver(this.getDriver());
        accountSetExt.setDb_url(this.getDb_url());
        accountSetExt.setDb_user_name(this.getDb_user_name());
        accountSetExt.setDb_password(this.getDb_password());
        accountSetExt.setMode(JSON.toJSONString(modeList));
        accountSetExt.setLog(true);
        return accountSetExt;
    }

    public SysAccountSetExt copy4Log() {
        SysAccountSetExt accountSetExt = new SysAccountSetExt();
        accountSetExt.setSid(this.getSid() + Constants.DATABASE_SUFFIX_FOR_LOG);
        accountSetExt.setCode(this.getCode() + Constants.DATABASE_SUFFIX_FOR_LOG);
        accountSetExt.setDb_host(this.getDb_host());
        accountSetExt.setDb_port(this.getDb_port());
        accountSetExt.setDb_name(this.getDb_name() + Constants.DATABASE_SUFFIX_FOR_LOG);
        accountSetExt.setDriver(this.getDriver());
        String dbUrl = this.getDb_url();
        String replaceStr = "/" + this.getDb_name() + "?";
        String targetStr = "/" + accountSetExt.getDb_name() + "?";
        dbUrl = dbUrl.replace(replaceStr, targetStr);
        accountSetExt.setDb_url(dbUrl);
        accountSetExt.setDb_user_name(this.getDb_user_name());
        accountSetExt.setDb_password(this.getDb_password());
        accountSetExt.setMode(JSON.toJSONString(Collections.singletonList("log")));
        accountSetExt.setLog(true);
        return accountSetExt;
    }

    public static SysAccountSetExt gen4Master(DruidDataSource masterDataSource, DataSourceProperties properties) throws Exception {
        DruidPooledConnection connection = masterDataSource.getConnection();
        SysAccountSetExt accountSetExt = new SysAccountSetExt();
        accountSetExt.setId(0L);
        accountSetExt.setSid(DataSourceContextHolder.DEFAULT_ACCOUNT_SET_SID);
        accountSetExt.setCode(DataSourceContextHolder.DEFAULT_ACCOUNT_SET_SID);
        Map<String, String> dbInfo = JdbcUtil.parseJdbcUrl(properties.getUrl());
        accountSetExt.setDb_host(dbInfo.get("host"));
        accountSetExt.setDb_port(Integer.parseInt(dbInfo.get("port")));
        accountSetExt.setDriver(properties.getDriverClassName());
        accountSetExt.setDb_name(connection.getCatalog());
        accountSetExt.setDb_url(properties.getUrl());
        accountSetExt.setDb_user_name(properties.getUsername());
        accountSetExt.setDb_password(properties.getPassword());
        accountSetExt.setMode(JSON.toJSONString(Arrays.asList("tsd", "master")));
        accountSetExt.setState(Constants.STATE_DB_CREATED);
        return accountSetExt;
    }

    public String genDbUrl(boolean withCatalog) {
        String dbUrl = Constants.MYSQL_DB_URL_TEMPLATE;
        if (!HlpUtils.isEmpty(this.getDb_host())) {
            dbUrl = dbUrl.replace("@host@", this.getDb_host());
        }
        if (!HlpUtils.isEmpty(this.getDb_port())) {
            dbUrl = dbUrl.replace("@port@", String.valueOf(this.getDb_port()));
        }
        if (withCatalog) {
            if (!HlpUtils.isEmpty(this.getDb_name())) {
                dbUrl = dbUrl.replace("@catalog@", this.getDb_name());
            }
        } else {
            dbUrl = dbUrl.replace("/@catalog@", "");
        }
        return dbUrl;
    }
}
